package countor;

import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 并发索引计数器计数，最大计数Long.MAX_VALUE*(Long.MAX_VALUE+1)<br>
 * 范围：-85070591730234615856620279821087277056~85070591730234615856620279821087277056
 * @author dingnate
 */
public class AtomIndexCountor<T> implements ICountor<T> {
	private T owner;
	// 宇宙实现方式
	private AtomicLong index = new AtomicLong(0);
	// 多维宇宙实现方式：最大计数 Long.MAX_VALUE的Integer.MAX_VALUE次方+Long.MAX_VALUE，想多了。。。
	//	private AtomicLongArray indexArray = new AtomicLongArray(Integer.MAX_VALUE);
	private AtomicLong counter = new AtomicLong(0);

	public AtomIndexCountor(T owner) {
		this.owner = owner;
	}

	public final void incr() {
		incr(1);
	}

	/**
	 * @param increment 支持正值负值
	 */
	public final void incr(long increment) {
		long postAdd = counter.addAndGet(increment);
		if (postAdd >= 0)
			return;
		long preAdd = postAdd - increment;
		if (preAdd >= 0) {
			if (increment > 0) {
				index.incrementAndGet();
				counter.set(postAdd - Long.MAX_VALUE);
				return;
			} else {
				index.decrementAndGet();
				counter.set(Long.MAX_VALUE + postAdd);
				return;
			}
		}
		while (counter.get() < 0)
			;
		incr(increment);
	}

	public final BigInteger getCount() {
		BigInteger counterValue = BigInteger.valueOf(counter.longValue());
		if (index.longValue() == 0)
			return counterValue;
		return BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(index.longValue())).add(counterValue);

	}

	public final T getOwner() {
		return owner;
	}

	@Override
	public String toString() {
		return "Counter [" + "count=" + getCount() + ", owner=" + owner + "]";
	}
}